其他
“软件开发教父” Martin Fowler 从业 40 年最想说这两个字!
The following article is from 异步社区 Author 异步社区
Martin Fowler,1963年出生在英格兰的沃尔索耳,正是编程世界刚刚起步的年代。Martin 在80年代初开始接触软件行业,那时候Smalltalk还是一门很火的语言,大家都在学习这门语言,而Martin也刚开始从事软件工作——关于信息系统对象建模方面的顾问。那个年代没有任何有关面向对象分析和设计的书籍,大家都是用一种简单的图符表示法,然后提出一个简单的建模过程,最后用几个简单的示例来加以说明。但Martin认为不应该把重点放在过程——即如何建模,而是把重点放在过程的结果——即模型本身,尽管这与当时大环境下的创建方式是相悖的。
Martin Fowler
就在去年,这位先行者又全面升级了《重构》,《重构:改善既有代码的设计(第2版)》面世了,国内外掀起一阵抢购热潮,豆瓣评分更是高达9.5分。说起重构,还要从1999年发生在Martin身上的一件事说起。面对凌乱的系统的核心继承体系,他建议负责该项目的经理将这些代码进行整理,但是被项目经理拒绝。随后,Martin把自己的想法第一时间告诉了在这个继承体系上工作的程序员,程序员都很敏锐, 马上就看出问题的严重性,特别是在这种需要借助外力才能发现问题。他们立刻用了两天的时间整理好这个继承体系,并删掉了其中一半代码,功能毫发无损,而且发现在继承体系中加入新的类或使用系统中的其他类都更快、更容易了,他们十分感谢Martin。但项目经理很不高兴,他觉得这些程序员却白白耗费了两天时间,做的工作却与未来几个月要交付的大量功能毫不相干,明明原先的代码运行起来还算正常,为什么要为了可能发生的问题去花费时间提前预防呢?不过在6个月之后,这个项目还是宣告失败了,原因是代码太复杂,无法调试,也无法将性能调优到可接受的水平。再后来,这个项目重新启动,唯一的解决办法就是从头开始编写整个系统,Kent Beck 受邀做了顾问。他做了几件迥异以往的事,其中最重要的一件就是听从Martin的建议,坚持以持续不断的重构行为来整理代码。那时,Martin第一次认识到重构的重要且不可替代性。“重构”这个概念最开始来自于 Smalltalk圈子,由于重构是框架开发中不可缺少的一部分,所以当框架设计者讨论自己的工作时,这个术语就诞生了。当他们精炼自己的类继承体系时,当他们叫喊自己可以拿掉多少多少行代码时,重构的概念慢慢浮出水面,后来重构就进入了其他编程语言阵营之中。说得直白一点,所谓重构(refactoring)就是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。重构是一种经千锤百炼形成的有条不紊的程序整理方法,可以最大限度地减小整理过程中引入错误的概率。本质上说,重构就是在代码写好之后改进它的设计。“在代码写好之后改进它的设计”这种说法有点儿奇怪。在软件开发的大部分历史时期,大部分人认为,应该先设计而后编码:首先得有一个良好的设计,然后才能开始编码。但是,随着时间流逝,人们不断修改代码,于是根据原先设计所得的系统,整体结构逐渐衰弱。代码质量慢慢沉沦,编码工作从严谨的工程堕落为胡砍乱劈的随性行为。而“重构”正好与此相反。哪怕手上有一个糟糕的设计,甚至是一堆混乱的代码,我们也可以借由重构将它加工成设计良好的代码。重构的每个步骤都很简单,甚至显得有些过于简单:只需要把某个字段从一个类移到另一个类,把某些代码从一个函数拉出来构成另一个函数,或是在继承体系中把某些代码推上推下就行了。但是,聚沙成塔,这些小小的修改累积起来就可以根本改善设计质量。这和一般常见的“软件会慢慢腐烂”的观点恰恰相反。有了重构以后,Martin发现工作的平衡点开始发生变化,例如,设计不是在一开始完成的,而是在整个开发过程中逐渐浮现出来。在系统构筑过程中,他学会了如何不断改进设计。这个“构筑-设计”的反复互动,可以让一个程序在开发过程中持续保有良好的设计。Martin认为,重构这东西不可能一开始就完全正确,它将随着设计者的经验成长而进化,代码被阅读和被修改的次数远远多于它被编写的次数。而保持代码易读、易修改的关键,就是重构。
《重构》自1999年面世以来,已经经过21年了。软件行业里新的编程语言不断涌现,老的编程语言也加快迭代,而函数式编程和面向对象一样成了主流编程语言的标配。不仅软件开发技术发生了很多重要的变化,各种软件开发工具也日益现代化,对开发的更好支持也已成为主流编程语言新的核心竞争力。而现在, “重构”这一理念已被读者广泛接纳,作为一种经千锤百炼形成的有条不紊的程序整理方法,能够最大限度地减小整理过程中引入错误的概率,成为编程的词汇表中不可或缺的部分,《重构》一书至今依旧被无数程序员奉为软件开发领域的经典之作。但重构的扎实功夫要学起来、做起来,颇不是件轻松的事,且不说详尽到近乎琐碎的重构手法,光是单元测试一事,怕是已有九成程序员无法企及,渐渐地,“重构”成了一块漂亮的招牌,大家都愿意挂上这个名号,可实际上干的却多是“刀劈斧砍”的勾当。就国内先如今的情况而论,“重构”概念的表里分离,大有愈演愈烈之势。随着当年的一线技术人员纷纷走上领导岗位,他们乐于将“重构”这块漂亮招牌用在更宽泛的环境下,例如系统架构乃至组织结构,都可以“重构”一下。然而基本功的欠缺,却也一路如影随形。当年在对象中的刀劈斧砍,如今被照搬到了架构、组织的调整。于是“重构”的痛苦回忆又一遍遍重演,甚而程度更深、影响更广、危害更烈。通过重构,现在的程序员普遍通过微增量来开发系统、编写测试用例。但Martin认为这远远不够,重构的影响其实应该更广泛,20年前,他和其他先行者鼓励大家都接受重构这一概念,但是,在整个行业普及重构仍需要相当长的时间。对于IT领域来说,Martin不仅仅是一个先行者,他还是一个引路者。Martin希望看到更多人使用他们大力推广的测试法,使用持续集成和持续交付等方法。但涉及上述概念,Martin觉得自己只能尽量在书中,从主客观上尽可能详尽地解释这些技术,并希望这会说服更多人进行尝试,“当他们尝到甜头后就会在工作中真正用上这些方法“。
点击图片,购买《重构:改善既有代码的设计(第2版)》
第1版里的代码已经很陈旧了,书里面还有Java.util.Vector; 一些重构并非是与面向对象紧耦合在一起的; Martin认为Java是一种非常严格的面向对象编程语言,而第1版中所有的重构都是基于面向对象的,他想通过再版来说明每个程序员都可以用任何(编程)语言、在任何环境中、遵循书中提到的范例进行重构,这也是他决定再版《重构》的源动力。
Martin Fowler
而说到重构工具,Martin和Kent做了很多年了,但他们从来没有意识到工具的重要性;当他们意识到这一点之后,他们感觉重构工具已经无处不在,他们认为这个内容非常重要,然后Martin就真把这些新内容加到新版中了。重构的关键是理念:通过进行最细微的改变,然后将这些变化串联起来,这就是重构思维核心。将一个大变化拆分为许多小变化,又在尽可能多进行细微变化的同时,不改变系统的整体表现,然后随时间推移,反复练习并思考如何进行拆分。Martin在《重构 2》一书中说过,他通过重构框架思考问题的体验,尝试各种高效的重构手法并做出决定,最重要的就是通过实践进行重构。他认为在尝试了不同的重构手法后,找出能重构手法生成理想序列,继而进行尝试识别出这种重构手法,而同样的逻辑也适用于更广泛的层面。因此,他采用了70多个种可行的重构,并且把每个重构都介绍了一种经过验证的代码变换手法的动机和技术。就像软件开发的大多数工作一样,重构除了动手做,别无他法,必须反复实践,必须在项目中使用重构。Martin始终希望,重构准则能帮助大家一步步修改自己的代码,减少了开发过程中的风险。在日新月异的 IT 技术世界里,不变的东西其实还是有的——重构。从《重构》的英文原版引进国内,到现在已经过去20年了。Martin Fowler 这次对本书进行的重构,体现了近年来编程领域的一些思潮变化,既有设计,又永远有改进空间。尽管时间是最强大的重构工具,连书里的示例语言都从 Java 变成 JavaScript 了,但书中的理念和实践的价值并没有随时间流逝。重构早就成了软件开发从业者本能的一部分,每个 IDE 都内置了重构功能,每个程序员都定期重构自己的代码。对于软件工程师来说,重构,并不是额外的工作,它就是编码本身。切实地读懂了《重构》的软件工程师,在能力上都会获得一个数量级的提升。
参考文献:
《分析模式:可重用对象模型》 作者:Martin Fowler
《UML精粹:一个简短的指南标准对象建模语言》 作者:Martin Fowler
《重构:改善既有代码的设计》 作者:Martin Fowler
软件开发教父,Martin Fowler:https://zhuanlan.zhihu.com/p/71216874
热 文 推 荐